home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Libraries / DCLAP 4j / DBio / DREnzyme.cpp < prev    next >
Encoding:
Text File  |  1995-12-17  |  37.6 KB  |  1,527 lines  |  [TEXT/R*ch]

  1. // DREnzyme.cp
  2. // d.g.gilbert
  3.  
  4.  
  5. #include <ncbi.h>
  6. #include <dgg.h>
  7. #include <DFile.h>
  8. #include <DList.h>
  9. #include <DApplication.h>
  10. #include <DWindow.h>
  11. #include <DControl.h>
  12. #include <DPanel.h>
  13. #include <DUtil.h>
  14. #include "DSequence.h"
  15. #include "DREnzyme.h"
  16.  
  17.  
  18. #if 1
  19. class DREnzymeGlobals {
  20. public:
  21.    DREnzymeGlobals() 
  22.        { 
  23.        DCodons::Initialize();
  24.        //DREMap::Initialize();
  25.        }
  26. };
  27.  
  28. static DREnzymeGlobals    globals; // initializes globals here
  29. #endif
  30.  
  31. extern Nlm_FonT  Nlm_fontInUse;
  32.  
  33.  
  34. // class DTableChoiceDialog
  35.  
  36. class DTableChoiceDialog : public DWindow {
  37. public: 
  38.     enum { cSetDefault = 3225, cChoose };
  39.     DPrompt    * fName;
  40.     DFile    * fFile;
  41.     Boolean fSetPref;
  42.     DTableChoiceDialog(char* title, char* desc=NULL, char* curfile = NULL);    
  43.     ~DTableChoiceDialog();        
  44.     Nlm_Boolean IsMyAction(DTaskMaster* action);
  45.     void OkayAction();
  46. };
  47.         
  48. DTableChoiceDialog::DTableChoiceDialog(char* title,char* desc,char* curfile) :
  49.     DWindow( 0, gApplication, fixed, -10, -10, -50, -20, title, kDontFreeOnClose),
  50.     fFile(NULL), fName(NULL), fSetPref(false)
  51. {
  52.     enum { cluwidth= 430 };
  53.     DCluster* clu;
  54.     DView* super;
  55.     if (desc) {
  56.         char buf[128];
  57.         sprintf(buf, "%s format", title);
  58.         clu= new DCluster( 0, this, 0, 0, false, buf);   
  59.         if (clu) super= clu; else super= this;
  60.         new DNotePanel(0, super, desc, cluwidth, 120);    
  61.         this->NextSubviewBelowLeft();
  62.         }
  63.  
  64.     if (curfile) fFile= new DFile(curfile,"r"); // in case user wants default !
  65.     clu= new DCluster( 0, this, 0, 0, false, "Current table");   
  66.     if (clu) super= clu; else super= this;
  67.     fName= new DPrompt( 0, super, curfile, cluwidth);
  68.     this->NextSubviewBelowLeft();
  69.  
  70.     new DButton( cChoose, this, "Choose file");
  71.     this->NextSubviewToRight();
  72.     new DCheckBox( cSetDefault,this,"Make this default table");
  73.     this->NextSubviewBelowLeft();
  74.     this->AddOkayCancelButtons(cOKAY,"Okay",cCANC,"Cancel");
  75. }
  76.  
  77. DTableChoiceDialog::~DTableChoiceDialog()
  78. {
  79.     if (fFile) delete fFile;
  80. }
  81.  
  82. Nlm_Boolean DTableChoiceDialog::IsMyAction(DTaskMaster* action) 
  83. {    
  84.     switch(action->Id()) {
  85.         case cChoose:
  86.             if (fFile) delete fFile;
  87.             if (gApplication->ChooseFile( fFile, NULL, "TEXT")) { 
  88.               fName->SetTitle( (char*)fFile->GetName());
  89.               gApplication->OpenDocument( fFile); // view it ??
  90.               }
  91.             return true;
  92.         default:
  93.             return DWindow::IsMyAction(action);    
  94.         }
  95. }
  96.  
  97. void DTableChoiceDialog::OkayAction() 
  98.     DWindow::OkayAction();
  99.     DCheckBox* ck = (DCheckBox*) this->FindSubview(cSetDefault);
  100.     if (ck && ck->GetStatus() && fFile && fFile->Exists()) {
  101.         fSetPref= true; 
  102.         }
  103. }
  104.  
  105.  
  106.     
  107. inline char* FlushLine( char* cp)
  108. {
  109.     char * ep;
  110.     while (*cp  && *cp <= ' ') cp++;
  111.     ep= StrChr(cp, '\0') - 1;
  112.     while (ep >= cp && *ep <= ' ') ep--;
  113.     ep[1]= 0;
  114.     //ep= StrChr(cp, ' '); if (ep) *ep= 0;
  115.     return cp;
  116. }
  117.  
  118.  
  119.  
  120.  
  121. #if 0
  122. // this isn't useful till we revise subclasses to be non-statics         
  123. // class DDataTable    
  124.  
  125. Nlm_Boolean DTableClass::NotAvailable()
  126. {
  127.     if (fState == kUnread) {
  128.         char * tablefile= gApplication->GetFilePref( fType, fSection, fDefaultvalue);
  129.         if (tablefile) ReadTable( tablefile);
  130.         else fState= kNodata;
  131.         if (fState != kOkay) Message(MSG_OK,"Could not read table file '%s'",tablefile);
  132.         }
  133.     return (fState != kOkay);
  134. }
  135.  
  136. void DTableClass::Initialize(char* type, char* section, char* defaultvalue)
  137. {
  138.     fState= kUnread;
  139.     fType= type;
  140.     fSection= section;
  141.     fDefaultvalue= defaultvalue;
  142. }
  143.  
  144. void DTableClass::ReadTable( char* tableFile)
  145. {
  146.      DFile aFile( tableFile, "r");
  147.     ReadTable( &aFile);
  148. }
  149.  
  150. //void DTableClass::TableChoice() = 0;
  151. //void DTableClass::ReadTable(DFile* aFile) = 0
  152.  
  153. #endif
  154.  
  155.  
  156.  
  157.  
  158.  
  159.     
  160. // struct CodonStat    
  161.     
  162. CodonStat::CodonStat( char* codn, char ami, float numk):
  163.     amino(ami), numPerK( numk)
  164. {
  165.     if (!codn) codn= "---";
  166.     codon[0]= codn[0]; 
  167.     codon[1]= codn[1]; 
  168.     codon[2]= codn[2]; 
  169.     codon[3]= codn[3]; 
  170. }     
  171.          
  172.          
  173. // class DCodons    
  174.  
  175. short DCodons::fState= DCodons::kUnread;
  176. short DCodons::fStartcodon= -1;
  177. CodonStat* DCodons::fCodons= NULL;
  178. char* DCodons::fType= "codon";
  179. char* DCodons::fSection= "data";
  180. char* DCodons::fDefaultvalue= "tables:codon.table";
  181.  
  182. Nlm_Boolean DCodons::NotAvailable()
  183. {
  184.     if (fState == kUnread) {
  185.         char * tablefile= gApplication->GetFilePref( fType, fSection, fDefaultvalue);
  186.         if (tablefile) ReadTable( tablefile);
  187.         else fState= kNodata;
  188.         if (fState != kOkay) Message(MSG_OK,"Could not read table file '%s'",tablefile);
  189.         }
  190.     return (fState != kOkay);
  191. }
  192.  
  193. void DCodons::Initialize(char* type, char* section, char* defaultvalue)
  194. {
  195.     fState= kUnread;
  196.     fType= type;
  197.     fSection= section;
  198.     fDefaultvalue= defaultvalue;
  199.     if (fCodons==NULL) fCodons= (CodonStat*) MemNew( 64 * sizeof(CodonStat));
  200. }
  201.  
  202. const char* DCodons::FindBestCodon( char matchamino)
  203. {
  204.     //shorten this x64 loop w/ sorted CodonTable sorted by most freq form/aa 
  205.     short k, bestk= -1;
  206.     float bestNumPerK= 0;
  207.     Boolean nomatch;
  208.     
  209.     for (k= 0, nomatch= true; k<64 && nomatch; k++) {
  210.         if (fCodons[k].amino == matchamino) {
  211.              if (bestk<0 || fCodons[k].numPerK > bestNumPerK) {
  212.                 bestk= k;
  213.                 bestNumPerK= fCodons[k].numPerK;
  214.                 }
  215.             }
  216.         else if (fCodons[k].amino > matchamino) {
  217.             nomatch= false;
  218.             }
  219.         }
  220.     if (bestk<0) return "NNN";  
  221.     else return fCodons[bestk].codon;
  222. }
  223.  
  224.  
  225.  
  226. void DCodons::TableChoice()
  227. {
  228.     char* title= "Codon Table";
  229.     char* desc = 
  230. "  gcg style, '..' signals start of data"LINEEND
  231. "AmAcid  Codon     Number    /1000     Fraction   .."LINEEND
  232. "Gly     GGG     1743.00      9.38      0.13"LINEEND
  233. "Gly     GGA     1290.00      6.94      0.09"LINEEND
  234. ;
  235.     char * tablefile= gApplication->GetFilePref( fType, fSection, fDefaultvalue);
  236.     
  237.     DTableChoiceDialog* win= new DTableChoiceDialog(title, desc, tablefile);
  238.     if (win->PoseModally()) {
  239.         ReadTable( win->fFile);
  240.         if (fState != kOkay) {
  241.             Message(MSG_OK, "Table wasn't properly loaded.  Please try again");
  242.             }
  243.         else if (win->fSetPref)
  244.             gApplication->SetPref((char*)win->fFile->GetName(), fType, fSection);
  245.         }
  246.     MemFree( tablefile);
  247.     delete win;
  248. }
  249.  
  250.  
  251. void DCodons::ReadTable( char* tableFile)
  252. {
  253.      DFile aFile( tableFile, "r");
  254.     ReadTable( &aFile);
  255.     //delete aFile;
  256. }
  257.  
  258. #ifdef WIN_MSWIN
  259. static int LIBCALLBACK
  260. #else
  261. static int
  262. #endif
  263. aminosort(void* a, void* b)
  264. {
  265.     return ( ((CodonStat*)a)->amino -  ((CodonStat*)b)->amino);
  266. }
  267.  
  268. void DCodons::ReadTable(DFile* aFile)
  269. {
  270. /*------ file format for codon table (gcg style)
  271. AmAcid  Codon     Number    /1000     Fraction   ..
  272.          1         2         3         4   
  273. 12345678901234567890123456789012345678901234567890
  274. Gly     GGG     1743.00      9.38      0.13
  275. Gly     GGA     1290.00      6.94      0.09
  276. ------*/
  277.     const    short kLinemax= 512;
  278.      Boolean done= FALSE;
  279.     char        amino3[5], codon[5], startc;
  280.     char        line[kLinemax];
  281.     short        na;
  282.     float        number, numPerK, frac;
  283.     
  284.     if (!aFile || !aFile->Exists()) return;
  285.     aFile->OpenFile();
  286.     do {
  287.         aFile->ReadLine( line, kLinemax);
  288.         done= (StrStr(line,"..") != NULL);
  289.     } while (!done && !aFile->Eof());
  290.     
  291.     done= FALSE;
  292.     startc= 0;
  293.     na= 0; 
  294.     while (!done && !aFile->Eof()) {
  295.         number= -1;
  296.         aFile->ReadLine( line, kLinemax); // eat line
  297.         if (*line > ' ') {
  298.             sscanf( line, "%3s %3s %f %f %f", &amino3, &codon, &number, &numPerK, &frac);
  299.             }
  300.         if (number > 0) {
  301.                     // use GCG practice of signifying start codon w/ all lowercase
  302.             fCodons[na].amino= DSequence::Amino321( amino3);
  303.           if (islower(amino3[0]) && islower(amino3[1]) && islower(amino3[2])) 
  304.                 startc= fCodons[na].amino;
  305.             codon[0]= toupper(codon[0]);
  306.             codon[1]= toupper(codon[1]);
  307.             codon[2]= toupper(codon[2]);
  308.             StrNCpy( fCodons[na].codon,codon,4);
  309.             fCodons[na].numPerK= numPerK;
  310.             na++;
  311.             }
  312.         done= na>= 64;
  313.         }
  314.     
  315.     if (done) {
  316.         Nlm_HeapSort(fCodons, 64, sizeof(CodonStat), aminosort);
  317.         if (!startc) startc= 'M'; // Met is usual start codon
  318.         for (short i= 0; i<64; i++) 
  319.           if (fCodons[i].amino == startc) { fStartcodon= i; break; }
  320.         fState= kOkay;
  321.         }
  322.     else fState= kNodata;
  323. }
  324.  
  325.  
  326.  
  327.  
  328.  
  329. // class DREnzyme
  330.  
  331.  
  332. DREnzyme::DREnzyme()
  333. {
  334.     fName= NULL;
  335.     fSite= NULL;
  336.     fCoSite= NULL;
  337.     fVendors= NULL;
  338.     fCutpoint = -1;
  339.     fCoCutpoint= -1;
  340.     fCut3from5 = 0;
  341.     fCutcount= 0;
  342. }
  343.  
  344. DREnzyme::~DREnzyme()
  345. {
  346.     MemFree( fName);
  347.     MemFree( fSite);
  348.     MemFree( fCoSite);
  349.     MemFree( fVendors);
  350. }
  351.  
  352.     
  353. Boolean DREnzyme::Parse( char* line)
  354. /*----
  355. [Name            Cut  Site                    ? !   Isoschizomers?                    >vendors ]
  356. ;AatI      3 AGG'CCT        0 !  Eco147I,StuI                 >OU
  357. AatII      5 G_ACGT'C      -4 !               >EGJLMNOPRSUVX
  358. AccI       2 GT'mk_AC       2 !               >ABDEGIJKLMNOPQRSUVXY
  359. ;AccII     2 CG'CG          0 !  Bsp50I,BstUI,MvnI,ThaI      >DEGJKQVXY
  360.  
  361. ? skip lines starting w/ ;
  362. ----*/
  363. {
  364.     //assume caller has eliminated blank lines 
  365.     short        i, k, l, len, sitel;
  366.     char        sitebuf[kMaxSite];
  367.     
  368.     if (*line == ';')  return false;
  369.     fCutpoint= 0;
  370.     fCut3from5= 0;
  371.  
  372.     i= 0; 
  373.     len= StrLen(line);
  374.     while (i<len && line[i]<=' ') i++;
  375.     k= i;
  376.     while (i<len && line[i]>' ') i++;
  377.     l= i-k;
  378.     fName= (char*) MemNew(l+1);
  379.     StrNCpy( fName, line+k, l); 
  380.     fName[l]= 0;
  381.     
  382.         //get cutpoint ?
  383.     while (i<len && line[i]<=' ') i++;
  384.     k= i;
  385.     while (i<len && line[i]>' ') i++;
  386.     l= i-k;
  387.     // word= copy(line,k,l); StringToNumber(word, long); fCutpoint= long; 
  388.     fCutpoint= atol(line+k);
  389.     
  390.         // get site && cutpoint 
  391.     while (i<len && line[i]<=' ') i++;    
  392.     k= i;
  393.     for (l= 0; i<len && line[i]>' ' && l<kMaxSite; i++) {
  394.         if (isalpha(line[i])) sitebuf[l++]= line[i];
  395.         }
  396.     sitel= l;
  397.     sitebuf[sitel]= 0;
  398.     fSite= (char*) MemNew(sitel+1);
  399.     MemCpy(fSite, sitebuf, sitel+1);
  400.     
  401.         //skip fCut3from5 value ?
  402.     while (i<len && line[i]<=' ') i++;
  403.     k= i;
  404.     while (i<len && line[i]>' ') i++;
  405.     //l= i-k;
  406.     fCut3from5= atol(line+k);
  407.  
  408.     //Boolean unsym= (fCut3from5 != 0 || sitel & 1);
  409.     if (1) {
  410. #if 1
  411.         long i;
  412.         char* aCoSite= (char*) MemNew(sitel+1);  
  413.         for (i=0; i<sitel; i++) aCoSite[sitel-i-1]= fSite[i];
  414.         aCoSite[sitel]= 0;
  415.             // ?? do complement before or after strcmp ?? likewise, reverse when?
  416.         DSequence::NucleicComplement( false, aCoSite, aCoSite, sitel);
  417.         if ( StringCmp(aCoSite, fSite) != 0) fCoSite= aCoSite;
  418.         else MemFree(aCoSite); 
  419. #else
  420.         long i, j;
  421.         char* aCoSite= (char*) MemNew(sitel+1);  
  422.         for ( i=0; i<sitel; i++) aCoSite[i]= fSite[i];
  423.         aCoSite[sitel]= 0;
  424.             // ?? do complement before or after strcmp ?? likewise, reverse when?
  425.         DSequence::NucleicComplement( false, aCoSite, aCoSite, sitel);
  426.         if ( StringCmp(aCoSite, fSite) != 0) {
  427.             for (i=0, j= sitel-1; i<j; i++, j--) {
  428.                 char c= aCoSite[i];
  429.                 aCoSite[i]= aCoSite[j];
  430.                 aCoSite[j]= c;
  431.                 }
  432.             aCoSite[sitel]= 0; // be sure ...
  433.             fCoSite= aCoSite;
  434.             }
  435.         else MemFree(aCoSite); 
  436. #endif
  437.  
  438. #if 1
  439.         fCoCutpoint= sitel - (fCutpoint + fCut3from5); 
  440. #else
  441.         if (fCut3from5) fCoCutpoint= sitel - (fCutpoint + fCut3from5); 
  442.         else fCoCutpoint= fCutpoint; // ?????? 
  443. #endif
  444.         }
  445.     
  446.     
  447.         //skip past "!"
  448.     while (i<len && line[i] != '!') i++;    
  449.     i++;
  450.         
  451.         //get Isoschizomers? -- not all have them! ?
  452.     while (i<len && line[i]<=' ') i++;
  453.     if (line[i] != '>') {
  454.         k= i;
  455.         while (i<len && line[i]>' ') i++;
  456.         l= i-k;
  457.             //skip past ">"
  458.         while (i<len && line[i] != '>') i++;
  459.         }
  460.     i++;
  461.     
  462.         //get vendors  
  463.     while (i<len && line[i]<=' ') i++;
  464.     k= i;
  465.     while (i<len && line[i]>' ') i++;
  466.     l= i-k; //Min(63,i-k);
  467.     fVendors= (char*) MemNew(l+1);
  468.     StrNCpy( fVendors, line+k, l); 
  469.     fVendors[l]= 0;
  470.     
  471.     return true;
  472. }
  473.         
  474.  
  475.  
  476. // class DREnzymeVendor
  477.  
  478.  
  479. DREnzymeVendor::DREnzymeVendor()
  480. {
  481.     fCode = '!';
  482.     fName    = NULL;
  483. }
  484.  
  485. DREnzymeVendor::~DREnzymeVendor()
  486. {
  487.     if (fName) MemFree( fName);
  488. }
  489.  
  490. Boolean DREnzymeVendor::Parse( char* line)
  491. // e.g.,  "A    Amersham (4/91)" 
  492. {
  493.     //assume caller has eliminated blank lines & flushed blanks from front & back 
  494. #if 1
  495.     char *cp= line;
  496.     fCode= *line;
  497.     line++;
  498.     while (*line && *line<=' ') line++;
  499.     fName= StrDup( line);
  500. #else
  501.     short        i, j, k, l, len;
  502.     len= StrLen(line);
  503.     for (i=0; i<len && line[i]<=' '; i++) ;
  504.     fCode= line[i];
  505.     i++;
  506.     while (i<len && line[i]<=' ') i++;
  507.     l= len-i;
  508.     fName= (char*) MemNew(l+1);
  509.     StrNCpy( fName, line+i, l); 
  510.     fName[l]= 0;
  511. #endif
  512.  
  513.     return true;
  514. }
  515.  
  516.  
  517.  
  518.  
  519.  
  520.  
  521.  
  522.  
  523.  
  524. // DREMap ---------------------------------
  525.         
  526.  
  527. short DREMap::fState= DREMap::kUnread;
  528. char* DREMap::fType= "renzyme";
  529. char* DREMap::fSection= "data";
  530. char* DREMap::fDefaultvalue= "tables:renzyme.table";
  531. DList    * DREMap::fREnzymes = NULL ;                // of DREnzyme ?? same as gREnzymes
  532. DList    * DREMap::fREnzymeVendors = NULL ;     // of DREnzymeVendor
  533.     
  534.     
  535. //static
  536. void DREMap::Initialize(char* type, char* section, char* defaultvalue)
  537. {
  538.     fREnzymes= NULL; //?
  539.     fREnzymeVendors= NULL; //?
  540.     fState= kUnread;
  541.     fType= type;
  542.     fSection= section;
  543.     fDefaultvalue= defaultvalue;
  544. }
  545.  
  546.  
  547.  
  548. DREMap::DREMap()
  549. {
  550.     fSeq= NULL;
  551.     fCoSeq= NULL;
  552.     fSeqCuts= NULL;
  553.     fCutcount= 0;
  554.     fCuttersCount= 0;
  555.     fType= "renzyme";
  556.     fSection= "data";
  557.     fDefaultvalue= "tables:renzyme.table";
  558. }
  559.  
  560. DREMap::~DREMap()  
  561. {
  562.     FreeTempData();
  563.     //FreeEnzymeList(); 
  564. }
  565.  
  566.  
  567.  
  568. //static
  569. void DREMap::FreeEnzymeList()
  570. {
  571.     fREnzymes = FreeListIfObject(fREnzymes); 
  572.     fREnzymeVendors = FreeListIfObject(fREnzymeVendors); 
  573. }
  574.  
  575. void DREMap::FreeTempData() 
  576. {
  577.     fSeq= NULL;
  578.     delete fCoSeq; fCoSeq= NULL;
  579.     MemFree(fSeqCuts); fSeqCuts= NULL;
  580.     fCutcount= 0;
  581.     fCuttersCount= 0;
  582. }
  583.  
  584. //static
  585. Nlm_Boolean DREMap::NotAvailable()
  586. {
  587.     if (fState == kUnread) {
  588.         char * tablefile= gApplication->GetFilePref( fType, fSection, fDefaultvalue);
  589.         if (tablefile) ReadTable( tablefile);
  590.         else fState= kNodata;
  591.         if (fState != kOkay) Message(MSG_OK,"Could not read table file '%s'",tablefile);
  592.         }
  593.     return (fState != kOkay);
  594. }
  595.  
  596. //static
  597. void DREMap::TableChoice()
  598. {
  599.     char* title= "R.Enzyme Table";
  600.     char* desc = 
  601. "    gcg format, '..' signals start of data"LINEEND
  602. "REBASE abbreviations for commercial sources of restriction enzymes"LINEEND
  603. "                A        Amersham (5/93)"LINEEND
  604. "                Y        P.C. Bio (9/91)"LINEEND
  605. "[Name            Cut  Site         Cut3-5 !   Isoschizomers?     >vendors]"LINEEND
  606. ".."LINEEND
  607. ";AatI      3 AGG'CCT        0 !  Eco147I,StuI         >OU"LINEEND
  608. "AatII      5 G_ACGT'C      -4 !                       >ELMNOPRSUX"LINEEND
  609. "AccI       2 GT'mk_AC       2 !                       >ABDEGKLMNOPQRSUX"LINEEND
  610. ";AccII     2 CG'CG          0 !  BstUI,MvnI,ThaI,Bsh1236I  >KQX"LINEEND
  611. ;
  612.     char * tablefile= gApplication->GetFilePref( fType, fSection, fDefaultvalue);
  613.  
  614.     DTableChoiceDialog* win= new DTableChoiceDialog(title, desc, tablefile);
  615.     if (win->PoseModally()) {
  616.         ReadTable( win->fFile);
  617.         if (fState != kOkay) {
  618.             Message(MSG_OK, "REnzyme table wasn't properly loaded.  Please try again");
  619.             }
  620.         else if (win->fSetPref)
  621.             gApplication->SetPref((char*)win->fFile->GetName(), fType, fSection);
  622.         }
  623.     MemFree( tablefile);
  624.     delete win;
  625. }
  626.  
  627. //static
  628. void DREMap::ReadTable( char* tableFile)
  629. {
  630.      DFile aFile( tableFile, "r");
  631.     ReadTable( &aFile);
  632.     //delete aFile;
  633. }
  634.  
  635. //static
  636. void DREMap::ReadTable(DFile* aFile)  
  637. /*------ file format for Restriction Enzyme table (REbase in wisconsin/GCG format)
  638. blah, blah
  639.  
  640. Commercial sources of restriction enzymes are abbreviated as follows:
  641.  
  642.         A    Amersham (4/91)
  643.         :        :
  644.          Y    P.C. Bio (9/91)
  645.  
  646. [Name            Cut  Site         Cut3-5 !   Isoschizomers?                    >vendors \newline]
  647. ..
  648. ;AatI      3 AGG'CCT        0 !  Eco147I,StuI                      >OU
  649. AatII      5 G_ACGT'C      -4 !         >EGJLMNOPRSUVX
  650. AccI       2 GT'mk_AC       2 !         >ABDEGIJKLMNOPQRSUVXY
  651. ;AccII     2 CG'CG          0 !  Bsp50I,BstUI,MvnI,ThaI            >DEGJKQVXY
  652.     :                        :
  653. ----------------*/
  654. {
  655.     const    short kLinemax = 512;
  656.     char                line[kLinemax+1];
  657.     Boolean         done, gotfirst;
  658.     char    * cp;
  659.  
  660.      if (!aFile || !aFile->Exists()) return;
  661.      
  662.     FreeEnzymeList();
  663.     fREnzymeVendors = new DList(); // of StringHandle 
  664.     fREnzymes    = new DList();    // of REnzymeHandle 
  665.  
  666.     aFile->OpenFile();
  667.     done= FALSE;            
  668.     gotfirst= FALSE;
  669.     while (!done && !aFile->Eof()) {
  670.         aFile->ReadLine( line, kLinemax);
  671.         done= StrStr(line, "sources of restriction enzymes") != NULL;
  672.         if (!done) {
  673.             gotfirst= TRUE;
  674.             done= StrStr(line, "Amersham") != NULL;  //vendor, maybe key line was changed...
  675.             }
  676.         }
  677.  
  678.         // Read vendor codes 
  679.     for (done= false; !done && !aFile->Eof(); ) {
  680.         if (!gotfirst) aFile->ReadLine( line, kLinemax);
  681.         gotfirst= false;
  682.         cp= FlushLine(line);
  683.         if (*cp) {
  684.             DREnzymeVendor* rev = new DREnzymeVendor();
  685.             if (rev->Parse( cp))
  686.                 fREnzymeVendors->InsertLast( rev);
  687.             else
  688.                 delete rev;
  689.             }
  690.         done= (StrStr(cp, "..") != NULL);  // GCG format data separator 
  691.         }
  692.     
  693.         // Read Enzymes 
  694.     for (done= false; !done && !aFile->Eof(); ) {
  695.         aFile->ReadLine( line, kLinemax);
  696.         cp= FlushLine( line);
  697.         if (*cp) {
  698.             DREnzyme*    re = new DREnzyme();
  699.             if (re->Parse( cp))
  700.                 fREnzymes->InsertLast( re);
  701.             else
  702.                 delete re;
  703.             }
  704.         }
  705.         
  706.     done= true; // !! need some test of acurrate read !!
  707.     if (done) {
  708.         fState= kOkay;
  709.         }
  710.     else fState= kNodata;
  711. }
  712.  
  713.  
  714. void DREMap::HuntCut( short n, short x, short& jlo)
  715. {    
  716.     short        jm, jhi, inc;
  717.     Boolean        done;
  718.  
  719.     jlo= 0; //TESTING....
  720.     
  721.     //- ascend= ((*fSeqCuts)^[n].fSeqIndex > (*fSeqCuts)^[1].fSeqIndex); 
  722.     if (jlo <= 0 || jlo > n) {
  723.         jlo= 0; 
  724.         jhi= n+1;
  725.         }
  726.         
  727.     else { // hunt from last low value section 
  728.         inc= 1;
  729.         if ( x >= fSeqCuts[jlo].fSeqIndex ) // ascend
  730.             do {
  731.                 jhi= jlo + inc;
  732.                 done= TRUE; 
  733.                 if (jhi > n)  
  734.                     jhi= n+1;
  735.                 else if ( x >= fSeqCuts[jhi].fSeqIndex ) {
  736.                     jlo= jhi; inc= inc + inc;
  737.                     done= FALSE; 
  738.                     }
  739.             } while (!done);
  740.             
  741.         else {
  742.             jhi= jlo;
  743.             do {
  744.                 jlo= jhi - inc;
  745.                 done= TRUE; 
  746.                 if (jlo < 1)
  747.                     jlo= 0;
  748.                 else if ( x < fSeqCuts[jlo].fSeqIndex) { //== ascend
  749.                     jhi= jlo; inc= inc + inc;
  750.                     done= FALSE;
  751.                     }
  752.             } while (!done);
  753.             }
  754.         }
  755.             // bisection 
  756.     while (jhi - jlo > 1) {
  757.         jm= (jhi + jlo) / 2;
  758.         if ( x > fSeqCuts[jm].fSeqIndex ) jlo= jm;
  759.         else if ( x == fSeqCuts[jm].fSeqIndex ) { jlo= jm; return; }
  760.         else jhi= jm;
  761.         }
  762. }        
  763.  
  764.  
  765. void DREMap::CutsAtBase( short atBase, short& firstCut, short& nCuts)
  766. {
  767.     short icut;
  768.         
  769.     nCuts= 0;
  770.     if ( fSeqCuts && fCutcount>0 ) {
  771.         /*-----
  772.         while ( ((*fSeqCuts)^[icut].fSeqIndex < atBase) do icut= icut+1;  
  773.         firstCut= icut;
  774.         ------*/
  775.         HuntCut( fCutcount, atBase, firstCut);    
  776.             //hunt may find middle of a run
  777.         while ( firstCut>1 && fSeqCuts[firstCut-1].fSeqIndex == atBase )
  778.             firstCut--;
  779.         icut= firstCut;  
  780.         while (fSeqCuts[icut].fSeqIndex == atBase) {
  781.             nCuts++;
  782.             icut++;
  783.             }
  784.         }
  785.     if (nCuts == 0) firstCut= 0; //??
  786. }
  787.  
  788.  
  789.  
  790. enum {     kSearchNotFound = -1, kStep = 1 };
  791.  
  792. long DREMap::QuickSearch( Nlm_Boolean first, char* target, long targlen, 
  793.                             char* source, long sourcelen)
  794. {
  795.     static long qIndex;
  796.     register char tBase; // fTargetbase
  797.     
  798.     tBase = target[0];
  799.     if (first) {
  800.         qIndex= -kStep;   
  801.         if (!tBase) return kSearchNotFound;
  802.         }
  803.  
  804. lNextStep:
  805.     qIndex += kStep; 
  806.     for (register long j= qIndex; j<sourcelen; j++) {  
  807.         if (tBase & source[j]) {
  808.             qIndex = j; 
  809.                         //? enough source left to match full target 
  810.             if (sourcelen-qIndex < targlen) 
  811.                 return kSearchNotFound;
  812.             else {
  813.               register char * sp = source + qIndex + 1;
  814.               register char * tp = target + 1;
  815.               for (register long k= targlen-1; (k); k--) 
  816.                   if ((*sp++ & *tp++) == 0) goto lNextStep; // no match
  817.                 return qIndex; // matched
  818.                 }
  819.             }
  820.         }
  821.     return kSearchNotFound;
  822.  
  823.     
  824.  
  825. void DREMap::SearchStrand( DSequence* bSeq, char* aTarget, char* sourcebits, long sourcelen,
  826.                                             DREnzyme* zyme, short cutAdd, long& zymecuts)
  827. {
  828.     long  targlen, i, len;
  829.   char   tb, * targbits;
  830.   
  831.   len= StrLen(aTarget);
  832.   targbits= (char*) MemNew(len+1);
  833.     for ( i=0, targlen = 0; i<len; i++) { 
  834.         tb = (char) DSequence::kMaskNucs & DSequence::NucleicBits(aTarget[i]);
  835.         if (tb) targbits[targlen++]= tb;
  836.         }
  837.   targbits[targlen]= 0;
  838.   
  839.     long indx= QuickSearch( true, targbits, targlen, sourcebits, sourcelen);
  840.     while (indx != kSearchNotFound) {
  841.         if (fCutcount >= fMaxcuts) {
  842.             fMaxcuts += 100;
  843.             fSeqCuts= (DRECutsItem*) MemMore( fSeqCuts, fMaxcuts * sizeof(DRECutsItem));
  844.             }
  845.         fSeqCuts[fCutcount].fSeqIndex= indx + cutAdd;
  846.         fSeqCuts[fCutcount].fREnzyme= zyme;
  847.         fCutcount++;
  848.         zymecuts++;
  849.         indx= QuickSearch( false, targbits, targlen, sourcebits, sourcelen);
  850.         }
  851.     MemFree(targbits);
  852. }
  853.         
  854.  
  855. void DREMap::FindCuts( DREnzyme* zyme, char* sourcebits, long sourcelen)
  856. {
  857.      long    zymecuts;
  858.  
  859. #if 0     
  860.     if (StringCmp(zyme->fName, "AlwI")==0) {
  861.         zymecuts= 0; // debug stop for misplaced zyme cutter
  862.         }
  863. #endif
  864.         
  865.     zymecuts= 0;
  866.     SearchStrand( fSeq, zyme->fSite, sourcebits, sourcelen, zyme, zyme->fCutpoint, zymecuts);
  867.  
  868.     if (zyme->fCoSite) {
  869.         // only do when 3' differs from 5' 
  870.         //!? ignore symmetric sites -- are these symmetric if fCut3!=fCut5
  871.         //!? also need to screen sites that are symmetric about cut points !?
  872.  
  873.         SearchStrand( fSeq, zyme->fCoSite, sourcebits, sourcelen, zyme, 
  874.                                     zyme->fCoCutpoint, zymecuts);
  875.         }
  876.     zyme->fCutcount= zymecuts;
  877.     if (zymecuts>0) fCuttersCount++;
  878. }
  879.  
  880.  
  881. #ifdef WIN_MSWIN
  882. static int LIBCALLBACK
  883. #else
  884. static int
  885. #endif
  886.  
  887. cutterCompare(void* a, void* b)
  888. {
  889.     short diff= ((DRECutsItem*)a)->fSeqIndex - ((DRECutsItem*)b)->fSeqIndex;
  890.     if (diff == 0) {
  891.         return StringCmp(((DRECutsItem*)a)->fREnzyme->fName, 
  892.                                   ((DRECutsItem*)b)->fREnzyme->fName);
  893.         }
  894.     else
  895.         return diff;
  896. }
  897.  
  898.  
  899. void DREMap::MapSeq( DSequence* aSeq)
  900. {
  901.     long  i, nzymes, len, sourcelen, aStart, aBases;
  902.     char * sourcebits, sb;
  903.     
  904.     FreeTempData();
  905.     if (NotAvailable()) return;
  906.     fSeq= aSeq;
  907.     fSeq->GetSelection( aStart, aBases);
  908.     aSeq->SetSelection(0,0); // for Complement...
  909.     fCoSeq= aSeq->Complement();
  910.     aSeq->SetSelection(aStart,aBases);  
  911.     
  912.     // make a NucBits form of fBases, once  
  913. #if 0
  914.         // this needs work -- draw currently expects start of seq/remap == 0, not aStart
  915.     if (aBases) {
  916.         len= aBases;
  917.         sourcebits= (char*) MemNew(len+1);
  918.         StrNCpy( sourcebits, aStart+fSeq->Bases(), len);
  919.         sourcebits[len]= 0;
  920.         }
  921.     else
  922. #endif
  923.     {
  924.     sourcebits= StrDup( fSeq->Bases());
  925.     len= StrLen(sourcebits);
  926.     }
  927.     for (i= 0, sourcelen= 0; i<len; i++) {
  928.         sb = (char) DSequence::kMaskNucs & DSequence::NucleicBits(sourcebits[i]);
  929.         if (sb) sourcebits[sourcelen++]= sb;
  930.         }
  931.   sourcebits[sourcelen]= 0;
  932.             
  933.     fCutcount= 0; 
  934.     fMaxcuts = 0;
  935.     fSeqCuts= (DRECutsItem*) MemNew(sizeof(DRECutsItem));
  936.     nzymes= fREnzymes->GetSize();
  937.     for (i=0; i<nzymes; i++) {
  938.         DREnzyme* re= (DREnzyme*) fREnzymes->At(i);
  939.         FindCuts( re, sourcebits, sourcelen);
  940.         }
  941.     MemFree( sourcebits);
  942.   
  943.     Nlm_HeapSort( fSeqCuts, fCutcount, sizeof(DRECutsItem), cutterCompare);
  944.     
  945.         // !! check for ident. zyme cuts at same site ?!!!
  946.   short at, lastat= -1;
  947.   char *name, *lastname=NULL;
  948.   for (i=0; i<fCutcount; i++) {
  949.       at= fSeqCuts[i].fSeqIndex;
  950.       name= fSeqCuts[i].fREnzyme->fName;
  951.       if (lastat == at && StringCmp(name, lastname)==0)
  952.         fSeqCuts[i].fREnzyme->fCutcount--;
  953.       lastname= name;
  954.       lastat= at;
  955.       }
  956. }
  957.  
  958.  
  959.  
  960.  
  961.  
  962.  
  963.  
  964. // class DBaseColors
  965.  
  966. short DBaseColors::fState= DBaseColors::kUnread;
  967. char* DBaseColors::fType= "color";
  968. char* DBaseColors::fSection= "data";
  969. char* DBaseColors::fDefaultvalue= "tables:color.table";
  970. baseColors DBaseColors::gAAcolors;
  971. baseColors DBaseColors::gNAcolors;
  972.     
  973. typedef unsigned long  colorVal;
  974.  
  975. Local colorVal        kBlack     = 0; 
  976. Local colorVal        kRed         = (255<<16);
  977. Local colorVal        kGreen     = (255<<8);
  978. Local colorVal        kBlue     = (255<<0);
  979. Local colorVal        kWhite     = 0xffffff00;
  980. Local colorVal         kYellow = (255<<16) | (255<<8);
  981. Local colorVal         kMagenta= (255<<16) | (255<<0);
  982. Local colorVal         kCyan     = (255<<8) | (255<<0);
  983. Local colorVal         kOrange = (255<<16) | (110<<8); // | 15<<0;
  984. Local colorVal         kOrange1 = (200<<16) | (110<<8); // | 15<<0; // this is brownish orange
  985. Local colorVal         kGreen1    = (200<<8) | (31<<16) | (21<<0);
  986. Local colorVal        kGray     = (127<<8) | (127<<16) | (127<<0);
  987. Local colorVal        kLtGray = (191<<8) | (191<<16) | (191<<0);
  988. Local colorVal        kDkGray = (63<<8) | (63<<16) | (63<<0);
  989.  
  990.  
  991. Nlm_Boolean DBaseColors::NotAvailable()
  992. {
  993.     if (fState == kUnread) {
  994.         char * tablefile= gApplication->GetFilePref( fType, fSection, fDefaultvalue);
  995.         if (tablefile) ReadTable( tablefile);
  996.         else fState= kNodata;
  997.         if (fState != kOkay) Message(MSG_OK,"Could not read table file '%s'",tablefile);
  998.         }
  999.     return (fState != kOkay);
  1000. }
  1001.  
  1002. void DBaseColors::Initialize(char* type, char* section, char* defaultvalue)
  1003. {
  1004.     fState= kUnread;
  1005.     fType= type;
  1006.     fSection= section;
  1007.     fDefaultvalue= defaultvalue;
  1008.     InitColors();
  1009. }
  1010.  
  1011. // static
  1012. void DBaseColors::TableChoice()
  1013. {
  1014.     char * title = "Base Color Table";
  1015.     char* desc = 
  1016. "[nacolors]"LINEEND
  1017. "; nucleic acid colors"LINEEND
  1018. "; base=color value ;add line for each base desired in set [' '..'~']"LINEEND
  1019. "; put two color values on a line for UPPER and lowercase bases"LINEEND
  1020. "A=0xffaa88"LINEEND
  1021. "C=0xaaff88"LINEEND
  1022. "G=0x8877ff"LINEEND
  1023. "T=0x88aaaa"LINEEND
  1024. "[aacolors]"LINEEND
  1025. "; amino acid colors"LINEEND
  1026. "A=0xaaff88"LINEEND
  1027. "B=0xffaa88"LINEEND
  1028. "; ... etc ..."LINEEND
  1029.  
  1030.     char * tablefile= gApplication->GetFilePref( fType, fSection, fDefaultvalue);
  1031.     DTableChoiceDialog* win= new DTableChoiceDialog(title,desc,tablefile);
  1032.     if (win->PoseModally()) {
  1033.         ReadTable( win->fFile);
  1034.         if (fState != kOkay) {
  1035.             Message(MSG_OK, "Table wasn't properly loaded.  Please try again");
  1036.             }
  1037.         else if (win->fSetPref)
  1038.             gApplication->SetPref((char*)win->fFile->GetName(), fType, fSection);
  1039.         }
  1040.     MemFree( tablefile);
  1041.     delete win;
  1042. }
  1043.  
  1044.  
  1045.  
  1046. static void ReadColors( char* colorstr, colorVal& ncolor1, colorVal& ncolor2, Boolean& twocolors)
  1047. {
  1048.         // this is failing to get correct color !!
  1049.         // sometimes no where near correct (grey -> black or white)
  1050.         // colorstr is read correctly into color1/color2
  1051.         // but SelectColor/GetColor pair loses it...
  1052.         
  1053.     unsigned short cr, cg, cb;
  1054.     //Nlm_Uint1  cr, cg, cb;
  1055.   unsigned long color1 = 0, color2 = 0;
  1056.     char * ep;
  1057.  
  1058.     ep= StrChr(colorstr,';'); if (ep) *ep= 0;
  1059.     colorstr= FlushLine( colorstr);
  1060.     twocolors= (StrChr(colorstr,' ') != NULL);
  1061.          // this works on Sol2, but %lx doesn't !
  1062.   sscanf( colorstr, "%li %li", &color1, &color2);  
  1063.   
  1064.     cr= (color1>>16) & 0xff;
  1065.     cg= (color1>>8) & 0xff;
  1066.     cb= (color1) & 0xff;
  1067. #ifdef WIN_MAC
  1068.     // color1 is correct format
  1069. #endif
  1070. #ifdef WIN_MSWIN
  1071.   color1 = (cr | cg << 8 | ((ulong)cb) << 16); //RGB (cr, cg, cb);
  1072. #endif
  1073. #ifdef WIN_MOTIF
  1074.     // X uses mapped values thru setcolor -- need to do the select/get dance
  1075.     Nlm_SelectColor( cr, cg, cb);
  1076.     color1= Nlm_GetColor();
  1077. #endif
  1078.     ncolor1= color1;
  1079.  
  1080.     if (twocolors) {
  1081.         cr= (color2>>16) & 0xff;
  1082.         cg= (color2>>8) & 0xff;
  1083.         cb= (color2) & 0xff;
  1084. #ifdef WIN_MAC
  1085.     // color2 is correct format
  1086. #endif
  1087. #ifdef WIN_MSWIN
  1088.   color2 = (cr | cg << 8 | ((ulong)cb) << 16); //RGB (cr, cg, cb);
  1089. #endif
  1090. #ifdef WIN_MOTIF
  1091.     // X uses mapped values thru setcolor -- need to do the select/get dance
  1092.         Nlm_SelectColor( cr, cg, cb);
  1093.         color2= Nlm_GetColor();
  1094. #endif
  1095.         ncolor2= color2;
  1096.         }
  1097. }
  1098.  
  1099.  
  1100. void DBaseColors::ReadTable( char* tableFile)
  1101. {
  1102.      DFile aFile( tableFile, "r");
  1103.     ReadTable( &aFile);
  1104. }
  1105.  
  1106.  
  1107. void DBaseColors::ReadTable(DFile* aFile)
  1108. {
  1109.     Boolean done= false;
  1110.     unsigned long*    curcolors;
  1111.     short      iline, nlines = 0;
  1112.     char    * line;
  1113.      char**    linelist;
  1114.  
  1115.     if (!aFile || !aFile->Exists()) return;
  1116.     colorVal savecolor= Nlm_GetColor();    
  1117.     
  1118.     aFile->Open("r");
  1119.      linelist= Dgg_ReadDefaultPrefs( aFile->fFile, &nlines);
  1120.     
  1121.     for (iline= 0; iline<nlines; iline++) {
  1122.         line= linelist[iline];
  1123.         if (line && *line) {
  1124.             if (*line == '[') { // sect name 
  1125.                 if (StrNICmp(line+1,"nacolor",7)==0)  
  1126.                     curcolors= &gNAcolors[0];
  1127.                 else if (StrNICmp(line+1,"aacolor",7)==0) 
  1128.                     curcolors= &gAAcolors[0];
  1129.                 else 
  1130.                     curcolors= NULL;
  1131.                 }
  1132.             else if (*line == ';') {
  1133.                 // skip comment
  1134.                 }
  1135.             else if (curcolors) {
  1136.                 char* colorval= StrChr(line, '=');
  1137.                 if (colorval) {
  1138.                         // look for 2 values in color value, up & lowcase char colors !?
  1139.                     Boolean     twocolors= false;
  1140.                     colorVal    ncolor1, ncolor2;
  1141.                     char basec= *line;
  1142.                     ::ReadColors( colorval+1, ncolor1, ncolor2, twocolors);
  1143.                     curcolors[ toupper(basec) - ' ']= ncolor1;
  1144.                     if (twocolors) ncolor1= ncolor2;
  1145.                     curcolors[ tolower(basec) - ' ']= ncolor1;    
  1146.                     }
  1147.                 }
  1148.             MemFree(line);
  1149.             }
  1150.         }
  1151.     MemFree(linelist);
  1152.  
  1153.     
  1154.     Nlm_SetColor(savecolor);
  1155.  
  1156.     done= true; // !! need some test of acurrate read !!
  1157.     if (done) {
  1158.         fState= kOkay;
  1159.         }
  1160.     else fState= kNodata;
  1161. }
  1162.  
  1163.  
  1164.     // make color palette like these into class
  1165.     // w/ file open/save methods, dialog choose color method
  1166.     // simplest dialog -- use r,g,b and gray switches
  1167.  
  1168. //static
  1169. void DBaseColors::InitColors() 
  1170. {
  1171.         // a static method for static vars
  1172.         // should call this Init routine from some local initializer class at startup
  1173.         // can't use the const values above -- not same for diff win systems
  1174.         //Nlm_SelectColor (Nlm_Uint1 red, Nlm_Uint1 green, Nlm_Uint1 blue)
  1175.         // ^^ this is safe for all win sys    
  1176.     colorVal savecolor= Nlm_GetColor();
  1177.     Nlm_SelectColor(   0,   0,   0); kBlack= Nlm_GetColor();
  1178.     Nlm_SelectColor( 255, 255, 255); kWhite= Nlm_GetColor();
  1179.     Nlm_SelectColor( 255,   0,   0); kRed= Nlm_GetColor();
  1180.     Nlm_SelectColor(   0, 255,   0); kGreen= Nlm_GetColor();
  1181.     Nlm_SelectColor(   0,   0, 255); kBlue= Nlm_GetColor();
  1182.     Nlm_SelectColor( 255, 255,   0); kYellow= Nlm_GetColor();
  1183.     Nlm_SelectColor( 255,   0, 255); kMagenta= Nlm_GetColor();
  1184.     Nlm_SelectColor(   0, 255, 255); kCyan= Nlm_GetColor();
  1185.     Nlm_SelectColor( 200,  89,  15); kOrange= Nlm_GetColor();
  1186.     Nlm_SelectColor(  31, 200,  31); kGreen1= Nlm_GetColor();
  1187.     Nlm_SelectColor( 127, 127, 127); kGray= Nlm_GetColor();
  1188.     Nlm_SelectColor( 191, 191, 191); kLtGray= Nlm_GetColor();
  1189.     Nlm_SelectColor(  63,  63,  63); kDkGray= Nlm_GetColor();
  1190.     Nlm_SetColor(savecolor);
  1191.     
  1192.     char ch;
  1193.     for (ch= ' '; ch <= '~'; ch++) { 
  1194.         gAAcolors[ch-' ']= kBlack; 
  1195.         gNAcolors[ch-' ']= kBlack; 
  1196.         }
  1197.     gNAcolors['A'-' ']= kRed;      
  1198.     gNAcolors['a'-' ']= kRed;
  1199.     gNAcolors['C'-' ']= kBlue;     
  1200.     gNAcolors['c'-' ']= kBlue;
  1201.     gNAcolors['G'-' ']= kGreen1; 
  1202.     gNAcolors['g'-' ']= kGreen1;
  1203.     gNAcolors['T'-' ']= kOrange;  
  1204.     gNAcolors['t'-' ']= kOrange;
  1205.     gNAcolors['U'-' ']= kOrange;
  1206.     gNAcolors['u'-' ']= kOrange;
  1207. }
  1208.  
  1209.  
  1210.  
  1211.  
  1212.  
  1213.  
  1214. // class DSeqStyle
  1215.  
  1216. short DStyleTable::fState= DStyleTable::kUnread;
  1217. char* DStyleTable::fType= "seqmasks";
  1218. char* DStyleTable::fSection= "data";
  1219. char* DStyleTable::fDefaultvalue= "tables:seqmasks.table";
  1220. DList* DStyleTable::fStyles= NULL;
  1221. DSeqStyle DStyleTable::fLaststyle;
  1222. char    DStyleTable::fLastch= 0;
  1223. char* DStyleTable::fToprow = NULL;
  1224. long    DStyleTable::fToprowlen= 0;
  1225.  
  1226.  
  1227. DSeqStyle::DSeqStyle() :
  1228.     name(NULL), description(NULL),
  1229.     fontname(NULL),fontsize(10), font(NULL),
  1230.     bold(false), italic(false), uline(false), uppercase(false), lowercase(false),
  1231.     dofontpat(false),invertcolor(false), framestyle(kFrameSolid),
  1232.     fontcolor(0), backcolor(0), framecolor(0), 
  1233.     doframecolor(false), dofontcolor(false), dobackcolor(false),
  1234.     repeatchar(0),frame(kFramenone)
  1235. {
  1236.     MemFill(fontpattern,0,sizeof(fontpattern));
  1237. }
  1238.  
  1239.  
  1240. DSeqStyle::~DSeqStyle()
  1241. {
  1242.     MemFree( name);
  1243.     MemFree( description);
  1244.     MemFree( fontname);
  1245. }
  1246.  
  1247. void DSeqStyle::GetFont()
  1248. {
  1249.     if (fontname) 
  1250.         font= Nlm_GetFont( fontname, fontsize, bold, italic, uline, NULL);
  1251.     if (dofontpat && !dobackcolor) {
  1252.         dobackcolor= true;
  1253.         backcolor= 0; // black!? always or not?
  1254.         }
  1255. }
  1256.  
  1257. DObject* DSeqStyle::Clone()  
  1258. {    
  1259.     DSeqStyle* astyle= (DSeqStyle*) DObject::Clone();
  1260.     astyle->name= StrDup( name);
  1261.     astyle->description= StrDup( description);
  1262.     astyle->fontname= StrDup( fontname);
  1263.     return astyle;
  1264. }
  1265.  
  1266.  
  1267.  
  1268. Nlm_Boolean DStyleTable::NotAvailable()
  1269. {
  1270.     if (fState == kUnread) {
  1271.         char * tablefile= gApplication->GetFilePref( fType, fSection, fDefaultvalue);
  1272.         if (tablefile) ReadTable( tablefile);
  1273.         else fState= kNodata;
  1274.         if (fState != kOkay) Message(MSG_OK,"Could not read table file '%s'",tablefile);
  1275.         }
  1276.     return (fState != kOkay);
  1277. }
  1278.  
  1279. void DStyleTable::Initialize(char* type, char* section, char* defaultvalue)
  1280. {
  1281.     fState= kUnread;
  1282.     fType= type;
  1283.     fSection= section;
  1284.     fDefaultvalue= defaultvalue;
  1285.     fStyles= new DList();
  1286.     fLastch= 0;
  1287.     fToprow = NULL;
  1288.     fToprowlen= 0;
  1289. }
  1290.  
  1291. void DStyleTable::ReadTable( char* tableFile)
  1292. {
  1293.      DFile aFile( tableFile, "r");
  1294.     ReadTable( &aFile);
  1295. }
  1296.  
  1297. void DStyleTable::ReadTable(DFile* aFile)
  1298. {
  1299.     Boolean done= false;
  1300.     short      iline, nlines = 0;
  1301.     char    * line;
  1302.      char ** linelist;
  1303.     DSeqStyle    *    astyle = NULL;
  1304.     char            * cp;
  1305.     Boolean     twocolors;
  1306.     colorVal    ncolor1, ncolor2;
  1307.     
  1308.     if (!aFile || !aFile->Exists()) return;
  1309.     colorVal savecolor= Nlm_GetColor();    
  1310.     fStyles->FreeAllObjects(); 
  1311.     
  1312.     aFile->Open("r");
  1313.      linelist= Dgg_ReadDefaultPrefs( aFile->fFile, &nlines);
  1314.     
  1315.     for (iline= 0; iline<nlines; iline++) {
  1316.         line= linelist[iline];
  1317.         if (line && *line) {
  1318.         
  1319.             if (*line == '[') { // sect name 
  1320.                 if (astyle) { astyle->GetFont(); fStyles->InsertLast(astyle); }  // save last one
  1321.                 astyle= new DSeqStyle();
  1322.                 cp= StrChr(line,']'); if (cp) *cp= 0;
  1323.                 astyle->name= StrDup(line+1); // ?? or do we use a "name=" variable?
  1324.                 }
  1325.                 
  1326.             else if (*line == ';') { // skip comment
  1327.                 }
  1328.                 
  1329.             else if (astyle) {
  1330.                 char* val= StrChr(line, '=');
  1331.                 if (val) {
  1332.                     *val++= 0;
  1333.                     while (isspace(*val)) val++;
  1334.                     
  1335.                     if (StrNICmp(line,"descr",5)==0) {
  1336.                         astyle->description= StrDup(val);
  1337.                         }
  1338.                     else if (StrNICmp(line,"repeat",6)==0) {
  1339.                         astyle->repeatchar= *val;
  1340.                         }
  1341.                     else if (StrNICmp(line,"frame",5)==0) {
  1342.                         if (StrNICmp(val,"box",3)==0) astyle->frame= DSeqStyle::kFramebox ;
  1343.                         else if (StrNICmp(val,"oval",3)==0) astyle->frame= DSeqStyle::kFrameoval ;
  1344.                         else if (StrNICmp(val,"round",3)==0) astyle->frame= DSeqStyle::kFramerrect ;
  1345.                         }
  1346.                     else if (StrNICmp(line,"boxstyle",5)==0) {
  1347.                         if (StrNICmp(val,"dashed",3)==0) astyle->framestyle= DSeqStyle::kFrameDashed ;
  1348.                         else if (StrNICmp(val,"dotted",3)==0) astyle->framestyle= DSeqStyle::kFrameDotted ;
  1349.                         else if (StrNICmp(val,"solid",3)==0) astyle->framestyle= DSeqStyle::kFrameSolid ;
  1350.                         else if (StrNICmp(val,"dark",3)==0) astyle->framestyle= DSeqStyle::kFrameDark ;
  1351.                         else if (StrNICmp(val,"medium",3)==0) astyle->framestyle= DSeqStyle::kFrameMedium ;
  1352.                         else if (StrNICmp(val,"light",3)==0) astyle->framestyle= DSeqStyle::kFrameLight ;
  1353.                         }
  1354.                     else if (StrNICmp(line,"style",5)==0) {
  1355.                         char* delims= ",;\t ";
  1356.                         char* word = StrTok(val, delims);
  1357.                         while (word) {
  1358.                             if (StrNICmp(word,"bold",3)==0) astyle->bold= true ;
  1359.                             else if (StrNICmp(word,"italic",3)==0) astyle->italic= true ;
  1360.                             else if (StrNICmp(word,"underline",3)==0) astyle->uline= true ;
  1361.                             else if (StrNICmp(word,"uppercase",3)==0) astyle->uppercase= true ;
  1362.                             else if (StrNICmp(word,"lowercase",3)==0) astyle->lowercase= true ;
  1363.                             else if (StrNICmp(word,"box",3)==0) astyle->frame= DSeqStyle::kFramebox ;
  1364.                             else if (StrNICmp(word,"frame",3)==0) astyle->frame= DSeqStyle::kFramebox ;
  1365.                             else if (StrNICmp(word,"invertcolor",3)==0) astyle->invertcolor= true ;
  1366.                             word= StrTok( NULL, delims);
  1367.                             }
  1368.                         }
  1369.                     else if (StrNICmp(line,"fontcolor",7)==0) {
  1370.                         ::ReadColors( val, ncolor1, ncolor2, twocolors);
  1371.                         astyle->dofontcolor= true;
  1372.                         astyle->fontcolor= ncolor1;
  1373.                         }
  1374.                     else if (StrNICmp(line,"backcolor",7)==0) {
  1375.                         ::ReadColors( val, ncolor1, ncolor2, twocolors);
  1376.                         astyle->dobackcolor= true;
  1377.                         astyle->backcolor= ncolor1;
  1378.                         }
  1379.                     else if (StrNICmp(line,"framecolor",7)==0 
  1380.                                 || StrNICmp(line,"boxcolor",6)==0) {
  1381.                         ::ReadColors( val, ncolor1, ncolor2, twocolors);
  1382.                         astyle->doframecolor= true;
  1383.                         astyle->framecolor= ncolor1;
  1384.                         }
  1385.                     else if (StrNICmp(line,"fontnam",7)==0) {
  1386.                         astyle->fontname= StrDup(val);
  1387.                         }
  1388.                     else if (StrNICmp(line,"fontsiz",7)==0) {
  1389.                         astyle->fontsize= atol(val);
  1390.                         }
  1391.                     else if (StrNICmp(line,"fillpat",7)==0  
  1392.                               || StrNICmp(line,"fontpat",7)==0) {
  1393.                         astyle->dofontpat= true;
  1394.                         char * pat= astyle->fontpattern;
  1395.                       sscanf( val, "%li %li", pat, pat+4);  
  1396.                         }
  1397.  
  1398.                     }
  1399.                 }
  1400.             MemFree(line);
  1401.             }
  1402.         }
  1403.     MemFree(linelist);
  1404.     if (astyle) { astyle->GetFont(); fStyles->InsertLast(astyle); }  // save last one
  1405.     Nlm_SetColor(savecolor);
  1406.  
  1407.     done= true; // !! need some test of acurrate read !!
  1408.     if (done)  fState= kOkay;
  1409.     else fState= kNodata;
  1410. }
  1411.  
  1412.  
  1413. // static
  1414. void DStyleTable::TableChoice()
  1415. {
  1416.     char * title = "Sequence Style Table";
  1417.     char * desc = 
  1418. "[mask1]"LINEEND
  1419. "description=This is my first mask"LINEEND
  1420. "style=bold,italic,box,underline,uppercase/lowercase,invertcolor"LINEEND
  1421. "repeatchar=. ; use if you want mult-align repeated chars set to this"LINEEND
  1422. "fontname=Times"LINEEND
  1423. "fontsize=12"LINEEND
  1424. "fontcolor=0xff0000"LINEEND
  1425. "backcolor=0x80e0e0"LINEEND
  1426. "boxcolor=0x00ff00"LINEEND
  1427. "fillpattern=0xffaa8877 0xccddeeff ; use 2 hex-long values for this 8-byte pattern"LINEEND
  1428. "[anothermask]"LINEEND
  1429. "description=my second mask"LINEEND
  1430. "; ... etc ..."LINEEND
  1431.  
  1432.     char * tablefile= gApplication->GetFilePref( fType, fSection, fDefaultvalue);
  1433.     DTableChoiceDialog* win= new DTableChoiceDialog(title,desc,tablefile);
  1434.     if (win->PoseModally()) {
  1435.         ReadTable( win->fFile);
  1436.         if (fState != kOkay) {
  1437.             Message(MSG_OK, "Table wasn't properly loaded.  Please try again");
  1438.             }
  1439.         else if (win->fSetPref)
  1440.             gApplication->SetPref((char*)win->fFile->GetName(), fType, fSection);
  1441.         }
  1442.     MemFree( tablefile);
  1443.     delete win;
  1444. }
  1445.  
  1446.  
  1447. void DStyleTable::StartDraw(char* toprowbases, long maxrow)
  1448. {
  1449.     fToprow= toprowbases; // any need to dup it?
  1450.     fToprowlen= maxrow;
  1451.     fLastch= 0;
  1452. }
  1453.  
  1454. void DStyleTable::EndDraw()
  1455. {
  1456.     fToprow= NULL;
  1457.     fLaststyle.ClearDrawing();
  1458.     fLastch= 0;
  1459. }
  1460.  
  1461. void DSeqStyle::ClearDrawing()
  1462. {
  1463.         // reverse the draw screen state
  1464.     if (font) ; // set saved font !?
  1465.     font= NULL;
  1466.     //if (invertcolor) Nlm_InvertColors(); // do before Black()
  1467.     Nlm_Black();
  1468.     fontcolor= 0; // == black
  1469.     if (dobackcolor) ; //??
  1470.     backcolor= 0;
  1471.     if (dofontpat) Nlm_Solid();
  1472.     dofontpat= false;
  1473. }
  1474.  
  1475. void DStyleTable::DrawBaseWithStyle( char ch, long baseindex, short maskval,     
  1476.                                                                       Nlm_RecT&    crec, short atrow)
  1477. {
  1478.     //short maskval= aseq->MaskAt(baseindex, masklevel);
  1479.     DSeqStyle* style= NULL;
  1480.     if (maskval) style= (DSeqStyle*) fStyles->At(maskval-1);
  1481.     if (!style) {
  1482.         Nlm_PaintChar(ch);
  1483.         return;
  1484.         }
  1485.         
  1486.     if (style->repeatchar && atrow>0 && fToprow && baseindex<fToprowlen && ch == fToprow[baseindex]) 
  1487.         ch= style->repeatchar;
  1488.     if (style->uppercase) ch= toupper(ch);
  1489.     else if (style->lowercase) ch= tolower(ch);
  1490.     
  1491.     if (style->font && (style->font != Nlm_fontInUse || style->font != fLaststyle.font)) 
  1492.         Nlm_SelectFont(style->font);  
  1493.     if (style->dofontcolor) {
  1494.         //if (style->fontcolor != fLaststyle.fontcolor) 
  1495.         Nlm_SetColor(style->fontcolor);
  1496.         }
  1497.     else {
  1498.         // !! Fix this -- pass "colors" param
  1499.         //if (ch!=fLastch) Nlm_SetColor( colors[ch-' ']);
  1500.         }
  1501.         
  1502.     if (style->invertcolor && !fLaststyle.invertcolor) Nlm_InvertColors();
  1503.     // ?? &/or Nlm_InvertRect( &crec);
  1504.     // #define  ShadeInvert()  { PaintRect(myRect);    TextMode(srcBIC); }
  1505.     // if (style->dobackcolor) { Nlm_SetColor(style->backcolor); Nlm_PaintRect(&crec);    TextMode(srcBIC); } //???
  1506.     // if (style->dofontpat) Dgg_PenPattern(fontpattern);  
  1507.     
  1508.     Nlm_PaintChar(ch);
  1509.     
  1510.     if (style->frame) switch (style->frame) {
  1511.         case DSeqStyle::kFramebox:     Nlm_FrameRect( &crec); break;
  1512.         case DSeqStyle::kFrameoval:  Nlm_FrameOval( &crec); break;
  1513.         case DSeqStyle::kFramerrect: Nlm_FrameRoundRect( &crec, 4,4); break;
  1514.         default: break;
  1515.         }
  1516.         
  1517.     fLastch= ch;
  1518.     fLaststyle= *style;
  1519. }            
  1520.  
  1521.  
  1522.  
  1523.